GitLAB-CI-CD
GitLab CI-CD
目录
[toc]
GitLabCI/CD简介
GitLabCI/CD简介
GitLabCI/CD是GitLab内置的持续集成与持续部署系统
- 开源: CI/CD是开源GitLab社区版和专有GitLab企业版的一部分。(极狐)
- 易于学习: 官方具有详细的学习操作文档。
- 无缝集成: CI/CD是GitLab的一部分,支持从计划到部署,具有出色的用户体验。 (例如:做一些基于版本控制系统的提交流水线、合并流水线,是很方便的!)
- 可扩展: 可以根据需要添加任意数量的构建节点。
- 更快的结果: 每个构建可以拆分为多个作业,这些作业可以在多台计算机上并行运行。
- 针对交付进行了优化: 多个阶段,手动部署, 环境 和 变量。
- 针对交付进行了优化: 多个阶段,手动部署, 环境和变量。
jenkins里,你想要获取git分支、git提交用户的话,我们都需要先去抓收据,去采集数据,进行一个过滤,再拿到;
但在gitlab里,使用gitlab ci时,里面就有现成的环境变量,我们直接使用就好,所以这一点,还是有很大的优势的。这个文档是大家在开发流水线时必须依赖的一个文档,使用时要注意下这里的版本!
配置完后,默认生效的。
- 我们再来运行一次流水线,观察下现象
可以看到,这里是并行运行作业的了,符合预期。
2. 流水线页面
- 1 清除runner的缓存;
- 2 进行CI文件语法校验;
- 3 手动触发运行流水线;
- 4 流水的步骤, 可以查看各个阶段的运行日志;
3. Pipeline编辑器
Pipeline开发工具与设置
1.Pipeline开发工具
可视化编辑器
变更.gitlab-ci.yml文件后, 可以通过Visualize
对CI文件中的定义进行可视化;
语法检测校验
通过Lint可以检测当前CI文件是否存在语法错误;若存在语法错误可以根据提示进行修正;
作业运行日志
一条流水线包含很多个作业,每个作业的运行日志可以在Jobs
界面看到。
Pipeline环境变量
代码直接写在gitlab的CI/CD
的editor里:
- 这里我们先修改下runner上的标签
- 运行
如果两个或者多个作业,指向同一个阶段名称,则该阶段下的所有作业都并行运行;如果不能并行运行,需要检查runner的配置文件中的concurrent
值, 要大于1。
variables 环境变量
变量可以分为全局变量和局部变量;全局变量是整个流水线可以用的,局部变量是仅在作业中生效的;
- CI代码
stages:- buildvariables:BUILD_TOOLS:value:"mvn"description:"choice build tools"#描述信息,注释不能用
RUNNER_TAG:"go"job1:tags:- "${RUNNER_TAG}"stage:buildvariables:BUILD_TOOLS:"gradle"script:- echo "${BUILD_TOOLS}"
- 运行
job 作业默认配置
定义一个作业的时候,一般定义哪些关键字呢? 作业在哪个runner运行? 作业属于流水线中的哪个阶段? 这个作业要做什么?
- CI代码
stages:- buildvariables:RUNNER_TAG:"go"before_script:- echo "pipeline before script"after_script:- echo "pipeline after script"job1:tags:- ${RUNNER_TAG}stage:buildbefore_script:- echo "before script...."script:- echo "mvn package"after_script:- echo "after script..."job2:tags:- ${RUNNER_TAG}stage:buildscript:- echo "build"
参数解析:
语法关键字 | 作用 | 备注 |
---|---|---|
variables | 定义作业中的环境变量; | |
tags | 根据标签选择运行作业的构建节点; | 多个标签, 则匹配具有所有标签的构建节点;GitLab14.1版本后, 标签的值可以使用变量;GitLab14.3版本后, 标签数量必须小于50; |
stage | 指定当前作业所属的阶段名称; | |
before_script | 作业在运行前执行的Shell命令行; | |
script | 作业在运行中执行的Shell命令行; | 每个作业至少要包含一个script; |
after_script | 作业在运行后执行的Shell命令行; |
- 运行
需要注意:如果
before_script和after_script
定义在pipeline里,则每个作业里都会运行这2个脚本;如果是定义在某个job里,则只会在其job里运行!
job 作业运行控制
语法关键字 | 作用 | 备注 |
---|---|---|
allow_failure | 控制作业状态,是否允许作业失败,默认值为false 。启用后,如果作业运行失败,该作业将在用户界面中显示橙色警告。![]() | 管道将认为作业成功/通过,不会被阻塞。 假设所有其他作业均成功,则该作业的阶段及其管道将显示相同的橙色警告。但是,关联的提交将被标记为"通过",而不会发出警告。 |
when | 根据状态控制作业运行,当前面作业成功或者失败时运行。 | on_success 前面阶段成功时执行(默认值);on_failure 前面阶段失败时执行;always 总是执行;manual 手动执行;delayed 延迟执行;start_in'5'5 seconds30 minutes1 day1 weeknever 永不执行; |
retry | 作业重新运行,遇到错误重新运行的次数。 | 值为整数等于或大于0,但小于或等于2异常分类 (一般就是3次) |
timeout | 作业运行超时时间; | |
rules | 根据特定的变量或文件变更来控制作业运行; | ifchangesexists |
needs | 作业依赖控制; | needs:["作业名称"] |
parallel | 生成多个作业,并行运行 | parallel:5值 2-50之间 |
parallel 并行运行
- 代码
stages:- buildvariables:RUNNER_TAG:"go"job1:tags:- ${RUNNER_TAG}stage:buildparallel:5script:- echo "mvn package"
模拟做压测。
- 运行
needs 作业关联运行
- CI代码
needs 指定要依赖的作业名称
stages:- build- testvariables:RUNNER_TAG:"go"job1:tags:- ${RUNNER_TAG}stage:buildscript:- echo "mvn package"- sleep 10job2:tags:- ${RUNNER_TAG}stage:buildscript:- echo "build"job3:tags:- ${RUNNER_TAG}stage:testscript:- echo "mvn package"job4:tags:- ${RUNNER_TAG}stage:testneeds:["job2"]script:- echo "mvn package"
- 运行
rules根据变量/文件控制
根据条件(变量)判断: IF
用法:
定义变量条件;运算符:●=●!=●=~条件链接符:●&&●||
CI代码:
variables:DOMAIN:example.comcodescan:stage:buildtags:- buildrules:- if:'$DOMAIN =="example.com"'when:manual- when:on_successscript:- echo "codescan"- sleep 5;
运行:
根据文件判断:changes
exists
changes
文件变更时条件为真;
示例: 代码提交后,当Dockerfile文件发生变更则条件为真。即手动执行此作业。
注意:非Push相关动作,此条件永远为真。
CI代码:
citest1:tags:- buildstage:testrules:- changes:- Dockerfilewhen:manual- when:neverscript:- echo "Do a test here"- echo "For example run a test suite"
运行:
直接运行次作业时,肯定是不会运行流水线的,因此此时是没有Dockerfile
文件的。
我们来创建一个Dockerfile
文件,再次运行流水线,并观察现象:
allow_failure
允许作业在不停止管道的情况下失败;
CI代码:
stages:- testcitest1:tags:- buildstage:testallow_failure:truescript:- lsl -l- echo "Do a test here"citest2:tags:- buildstage:testscript:- ls -l- echo "Do a test here"
运行:
variables
重新定义变量的值;
示例: 如果当前的分支是主干分支main, 则重新定义ENV_TYPE
的值为prod
。
注意: 只影响局部作业内的变量,不会影响全局变量。
CI代码:
variables:ENV_TYPE:"dev"cddeploy:tags:- buildstage:deployrules:- if:$CI_COMMIT_REF_NAME =="main"variables:ENV_TYPE:"prod"script:- echo "Deploy env ${ENV_TYPE}"
运行:
🍀 某一类文件写法:
when
同when语法的运行方式;
这里的when是写在rules里面的,也可以写在外面的。
rules代码汇总:
stages:- build- testvariables:RUNNER_TAG:"go"SKIP_BUILD:"true"job1:tags:- ${RUNNER_TAG}stage:buildrules:- if:'$SKIP_BUILD =="true"'# 此时job1 不会被运行when:never- when:alwaysbefore_script:- echo "before script...."script:- echo "mvn package"after_script:- echo "after script..."job2:tags:- ${RUNNER_TAG}stage:testrules:- changes:- README.md# 提交时仅该文件存在变更时才会触发when:always- when:neverscript:- echo "test"job3:tags:- ${RUNNER_TAG}stage:testrules:- exists:- Dockerfile#只要项目中存在该文件就会运行,提交存在也算。when:manual- when:neverscript:- echo "test"job4:tags:- ${RUNNER_TAG}stage:testscript:- echo "test"
运行:
when 状态控制和运行方式
- 根据上游作业的状态决定
- 当前作业是否运行?
- 运行的方式?(手动/自动/定时)
CI代码:
stages:- build- test- deployvariables:RUNNER_TAG:"go"job1:tags:- ${RUNNER_TAG}stage:buildbefore_script:- echo "before script...."script:- echo "mvn package"after_script:- echo "after script..."job2:tags:- ${RUNNER_TAG}stage:testwhen:on_successscript:- echo "build"job3:tags:- ${RUNNER_TAG}stage:testwhen:on_failurescript:- echo "build"job4:tags:- ${RUNNER_TAG}stage:deploywhen:manualscript:- echo "build"
运行:
when:delay
test1:tags:- ${RUNNER_TAG}stage:testscript:- echo "Do a test here"- echo "For example run a test suite"- sleep 3when:delaystart_in:'5'
timeout作业运行超时时间
build:script:build.shtimeout:3 hours 30 minutestest:script:rspectimeout:3h 30m
retry 作业失败后重试次数
CI代码:
stages:- build- testvariables:RUNNER_TAG:"go"job1:tags:- ${RUNNER_TAG}stage:buildretry:2before_script:- echo "before script...."script:- echo "mvn package"- mvsafter_script:- echo "after script..."job2:tags:- ${RUNNER_TAG}stage:testscript:- echo "build"
运行:
根据特定的错误匹配:
always :在发生任何故障时重试(默认)。unknown_failure :当失败原因未知时。script_failure :脚本失败时重试。api_failure :API失败重试。stuck_or_timeout_failure :作业卡住或超时时。runner_system_failure :构建节点的系统发生故障。missing_dependency_failure:依赖丢失。runner_unsupported :Runner不受支持。stale_schedule :无法执行延迟的作业。job_execution_timeout:作业运行超时。archived_failure :作业已存档且无法运行。unmet_prerequisites :作业未能完成先决条件任务。scheduler_failure :调度失败。data_integrity_failure :结构完整性问题。####max :最大重试次数 when :重试失败的错误类型stages:- build- testvariables:RUNNER_TAG:"go"job1:tags:- ${RUNNER_TAG}stage:buildretry:2# 不管任何错误,都重试2次before_script:- echo "before script...."script:- echo "mvn package"- mvs# 命令错误after_script:- echo "after script..."job2:tags:- ${RUNNER_TAG}stage:testwhen:on_failure# 为了让这个作业运行所以添加的,不然前面作业失败这个作业就不运行了。script:- echo "build"- aaa# 命令错误retry:max:2#when:api_failurewhen:script_failure# 定义脚本错误: 正常会retry两次
运行:
allow_failure 允许作业失败
CI代码:
stages:- build- testvariables:RUNNER_TAG:"go"job1:tags:- ${RUNNER_TAG}stage:buildallow_failure:trueretry:2before_script:- echo "before script...."script:- echo "mvn package"- mvsafter_script:- echo "after script..."job2:tags:- ${RUNNER_TAG}stage:testscript:- echo "build"
运行:
Pipeline运行控制
1.workflow 控制流水线
控制管道是否创建和运行。根据条件(变量)判断: IF
if 定义变量条件;
variables 重新定义变量的值;
when
- always
- never
命令 | 备注 |
---|---|
if:'$CI_PIPELINE_SOURCE =="merge_request_event"' | 合并请求时运行流水线; |
if:'$CI_PIPELINE_SOURCE =="push"' | 提交代码运行流水线; |
- 预定义变量